home *** CD-ROM | disk | FTP | other *** search
- *
- *
- * FLANGE.ASM - flanging effect for TI DSK module.
- *
- *
-
- *
- * Knobs - adjust these values within suggested range for
- * variations on the effect.
- *
- * Patch Name Dry Wet FB Step Range Delay
- * Very slow flange 07fffh 07fffh 00000h 0008h 060h 0000h
- * Flange w/ FB 07fffh 07fffh 06800h 0020h 050h 0000h
- * Invert flange 07fffh 08000h 00000h 000eh 060h 0000h
- * Invert w/ invert FB 07fffh 08000h 0a000h 0012h 060h 0000h
- * Fast flange 07fffh 07fffh 01000h 0180h 038h 0008h
- * Chorus 07fffh 07fffh 0000h 0040h 070h 0350h
- *
- DRY_LEVEL .set 07fffh ; (0 - 07fffh dry signal level)
- WET_LEVEL .set 07fffh ; (08000h - 07fffh wet signal level)
- FB_LEVEL .set 01000h ; (08000h - 07fffh regeneration amount)
- SWEEP_STEP .set 00080h ; (01h - 07fffh sweep rate)
- SWEEP_RANGE .set 00050h ; (010h - 03e0h sweep width)
- SWEEP_DELAY .set 00000h ; (0 - 3e0h delay)
-
- *
- * Misc. defines
- *
- BUF .set 0410h ; main circular buffer start and end
- BUFEND .set 0800h
- SWEEPUP .set 0 ; flag value for AR5
- SWEEPDOWN .set 1 ; ditto
-
- *
- * Data storage
- *
- SWEEPCNT .set 00h ; primary interp factor
- SWEEPCOMP .set 01h ; complement of interp factor
- STEP .set 02h ; inc/dec value for sweepcnt
- TMP .set 03h ; temporary storage reg
- INPVAL .set 04h ; input value
- OUTVAL .set 05h ; output value
- FEEDBACK .set 06h ; mix params...
- WET .set 07h
- DRY .set 08h
-
- .include "setup.asm"
-
- *
- * main
- *
- main:
- ssxm ; set sign extension mode
- spm 1 ; set P shift for Q15 (1 bit left shift
- ; from P => accum)
- ldpk 8 ; data at 0400h
-
- lrlk AR0,BUFEND ; permanently point to end of mem buf
- lrlk AR1,BUF ; write ptr, point to start of mem buf
- lrlk AR4,SWEEP_RANGE ; breadth of sweep
- sar AR4,TMP
- lalk SWEEP_DELAY ; add in delay factor for chorus effects
- add TMP
- sacl TMP
- lalk BUFEND ; calc starting point for read ptrs
- sub TMP ; end of buf minus sweep range
- subk 1 ; keep 'em from getting too close to write ptr
- sacl TMP
- lar AR2,TMP ; load 1st read ptr
- lar AR3,TMP ; 2nd read ptr, initial value for first access
- lrlk AR5,SWEEPUP ; set initial sweep direction
- lack 0
- sacl SWEEPCNT ; set initial fractional sweep
- lalk SWEEP_STEP ; install sweep rate
- sacl STEP
- lalk FB_LEVEL
- sacl FEEDBACK ; delayed signal feedback mix
- lalk WET_LEVEL
- sacl WET ; delayed signal output mix
- lalk DRY_LEVEL
- sacl DRY ; straight signal output mix
-
- lack 014h ; enable AIC recv interrupts
- ldpk 0
- sacl IMR
-
- ; loop here forever processing interrupts
- loop: idle
- b loop
-
- *
- * rint
- *
- * Recv interrupt handler performs all the work. Since there is
- * no main thread, there is no need to save or restore regs.
- * We can assume:
- *
- * AR0 - points to end of buffer
- * AR1 - current write ptr
- * AR2 - 1st read ptr
- * AR3 - 2nd read ptr
- * AR4 - sweep range counter
- * AR5 - sweep direction flag
- *
- rint:
- ; note: no need to save/restore processor state since
- ; main thread does absolutely nothing
-
- sovm ; set clipping overflow mode for the
- ; "analog" processing
- ldpk 0
- lac DRR ; read in new input value
- ldpk 8
- sfr ; dump low 2 junk bits
- sfr
- sacl INPVAL ; temporary storage
-
- ; interpolate ouput value from the two read ptrs
- lalk 32767 ; develop complement of fractional
- sub SWEEPCNT ; sweep position
- sacl SWEEPCOMP
- larp AR2 ; use 1st read ptr
- lt SWEEPCNT ; get fractional sweep position
- mpy *,AR3 ; scale 1st read value
- ltp SWEEPCOMP
- mpy *,AR1 ; scale 2nd read value
- apac ; glob 'em together
- sach OUTVAL ; this will be our "wet" output value
-
- ; do feedback
- lt OUTVAL
- mpy FEEDBACK ; scale feedback to taste
- pac
- addh INPVAL
- sach *+ ; store finished input value thru AR1
- cmpr 0 ; check for wrap on store ptr
- bbz nowrap1,*,AR5 ; (arp to directon flag)
- lrlk AR1,BUF
- nowrap1:
-
- ; do level scaling on direct and wet
- lt OUTVAL
- mpy WET ; scale wet signal
- pac
- lt INPVAL ; get original input value
- mpy DRY ; scale dry signal
- apac ; generate composite final output
- sach OUTVAL
- lac OUTVAL ; prepare final output for AIC
- andk 0fffch ; clear lowest 2 bits
-
- ldpk 0
- sacl DXR ; do output
- ldpk 8
-
- ;
- ; now update our sweep stuff, 1st see which direction we're going
- ;
- rovm ; normal overflow operation for arithmetic
- banz down,*,AR2
-
- ;
- ; UPWARD SWEEP (delay decreasing sweep)
- ;
- ; always move forward at least one notch
- sar AR2,TMP ; copy AR2 to AR3
- lar AR3,TMP
- mar *+ ; inc AR2
- cmpr 0
- bbz nowrap2,*,AR3
- lrlk AR2,BUF
- nowrap2:
- ; now update fractional delay
- zac ; clear accum
- addh SWEEPCNT ; use high accum for calc
- addh STEP
- sach SWEEPCNT
- bnv done,*,AR2 ; fractional part didn't overflow,
- ; no need to advance sweep further
-
- ; fractional portion overflowed, adjust main sweep forward
- sar AR2,TMP ; move AR2 to AR3
- lar AR3,TMP
- mar *+ ; inc AR2
- cmpr 0
- bbz nowrap3,*,AR4 ; (arp to sweep cnt AR4)
- lrlk AR2,BUF
- nowrap3:
- lac SWEEPCNT
- andk 07fffh ; mask sign bit
- sacl SWEEPCNT
-
- ; adjust main sweep counter
- mar *-
- banz done
-
- ; main sweep expired, reload, swap step sign
- lrlk AR4,SWEEP_RANGE
- lac STEP ; invert sign of step value
- neg
- sacl STEP
- lark AR5,SWEEPDOWN ; show new direction
- b done
-
- ; DOWNWARD SWEEP (delay increasing)
- down:
- lac SWEEPCNT
- add STEP ; step is negative here so we're actually
- sacl SWEEPCNT ; subtracting
- blz underflow,*,AR2 ; cnt went less than zero, skip ptr advance
-
- ; no underflow, advance ptrs but skip rest of sweep updates
- sar AR2,TMP ; copy AR3 to AR2
- lar AR3,TMP
- mar *+ ; inc AR2
- cmpr 0
- bbz done
- lrlk AR2,BUF
- b done
-
- ; fractional portion underflowed, update major sweep
- underflow:
- lac SWEEPCNT ; mask off sign stuff from underflow
- andk 07fffh
- sacl SWEEPCNT
- larp AR4
- mar *-
- banz done
-
- ; main sweep expired, reload, swap step sign
- lrlk AR4,SWEEP_RANGE
- lac STEP ; invert sign of step value
- neg
- sacl STEP
- lark AR5,SWEEPUP ; show new direction
-
- ;
- ; DONE
- ;
- done:
- eint
- ret
-
-
- *
- * tint
- *
- * Timer interrupt - not used.
- *
- tint:
- eint
- ret
-
- *
- * xint
- *
- * AIC xmit interrupt - not used.
- *
- xint:
- eint
- ret
-